import { reactive, computed, watch, toRaw, readonly } from "vue";
import { MenuNodeClass, OrgDataClass, MenuNodeInterface } from "@/model/AppModel";
import { MgrUserDataClass } from "@/model/MgrUser";
import { v4 } from "uuid";
import { queryGet, setStorage, getStorage } from "@/utils/api";
import { menus, btnList } from "@/config/menus"

const state = reactive<{
  /**
   * 应用是否已经初始化
   */
  isAppCreated: boolean;

  /**
   * 应用是否展示
   * 每次刷新都会重置
   */
  isAppShow: boolean;

  /**
   * token
   */
  token: string;

  /**
   * 用户权限
   */
  grantType: number;

  /**
   * 菜单是否被收起
   */
  menuCollapse: boolean;

  /**
 * 页面唯一值,每次页面都有一个新的值
 */
  pageuuid: string;

  /**
   * 用户信息
   */
  userInfo: MgrUserDataClass;

  /**
   * 菜单栏信息
   * 树状结构
   */
  menus: MenuNodeClass[];

  /**
 * 菜单栏信息
 * 数组结构
 */
  menusArray: MenuNodeClass[];

  /**
   * 按钮权限映射
   */
  menuActionMap: {
    [key: string]: {
      [key: string]: boolean
    }
  },
  /**
   * 组织列表
   */
  orgListAll: OrgDataClass[]
}>({
  isAppCreated: false,
  isAppShow: false,
  userInfo: new MgrUserDataClass({}),
  menus: [],
  menusArray: [],
  token: "",
  menuCollapse: false,
  pageuuid: "",
  menuActionMap: {},
  orgListAll: [],
  grantType: 0,
})

/**
 * state只能是只读的
 */
export const appState = readonly(state);

/**
 * 展示实际的菜单栏
 * 不用appstate.menus 的原因是 他是只读的 , 再appMenuItem页面中ts提示有问题
 */
export const showMenus = computed<MenuNodeClass[]>(() => state.menus);

/**
 * 要想在外部修改state中数据,
 * 只能通过appAction
 */
export const appAction = {
  setIsAppCreated(value: boolean) {
    state.isAppCreated = value;
  },
  /**
   * 修改展示appShow
   */
  setIsAppShow(value: boolean) {
    state.isAppShow = value;
  },
  /**
   * 控制左侧菜单栏是否收起
   */
  setMenuCollapse(collapse: boolean) {
    state.menuCollapse = collapse;
  },
  /**
 * 创建一个新的页面唯一值
 */
  resetPageuuid() {
    state.pageuuid = v4().split("-").join("");
  },
  /**
   * 更新用户token
   */
  setToken(token: string) {
    state.token = token;
  },

  /**
   * 更新用户权限
   */
  setGrantType(value: number) {
    state.grantType = value;
  },

  /**
   * 更新登录用户
   */
  setUserInfo(value: MgrUserDataClass) {
    state.userInfo = value;
  }
}

/**
 * 获取菜单权限 和 菜单按钮权限
 */
// export const getMenuActionList = async function (): Promise<void> {
//   state.menus = [];

//   return new Promise((resolve, reject) => {
//     Promise.all([
//       queryGet({
//         docType: "Menu",
//         actionType: "LoginInfo",
//         apiType: "SingleList"
//       }),
//       queryGet({
//         docType: "MenuAction",
//         actionType: "LoginInfo",
//         apiType: "SingleList"
//       })
//     ])
//       .then((res: any[]) => {
//         //根据SortNum将列表进行正向排序
//         let newList = res[0].sort(function (a: any, b: any) {
//           return a.SortNum - b.SortNum;
//         });
//         //菜单
//         let menus: MenuNodeClass[] = newList.map((item: any) => {
//           return new MenuNodeClass({
//             id: item.Id,
//             title: item.Name,
//             parentId: item.ParentId,
//             pageName: item.Key,
//             icon: item.Icon ? FILE_URL + item.Icon : ""
//           });
//         });

//         state.menusArray = menus.concat([]);

//         // 按钮权限
//         let menuAction = res[1];

//         //将按钮权限 添加到菜单中去
//         for (let item of menuAction) {
//           let selectMenu = menus.find((menuItem) => {
//             return menuItem.id == item.Id;
//           })
//           if (selectMenu) {
//             selectMenu.actionMap[item.Key] = true;
//           }
//         }

//         for (let item of menus) {
//           state.menuActionMap[item.pageName] = item.actionMap
//         }

//         //生成菜单列表
//         let list: MenuNodeClass[] = menus;
//         function fun(parentId: number): any[] {
//           let outList: MenuNodeClass[] = [];
//           let inList: MenuNodeClass[] = [];
//           for (let item of list) {
//             if (item.parentId == parentId) {
//               inList.push(item)
//             } else {
//               outList.push(item);
//             }
//           }
//           list = outList;
//           for (let item of inList) {
//             item.list = fun(item.id);
//           }
//           return inList;
//         }
//         state.menus = fun(0);

//         resolve();
//       })
//       .catch(reject)
//   })
// }


/**
 * 获取用户身份
 */
export const getUserInfo = function (): Promise<void> {
  return new Promise((resolve, reject) => {
    queryGet({
      docType: "Account",
      actionType: "LoginInfo",
      apiType: "Single"
    })
      .then(res => {
        appAction.setUserInfo(new MgrUserDataClass(res));
        resolve();
      })
      .catch(reject)
  })
}

/**
 * 获取菜单权限
 */
export const getMenuActionList = function (): Promise<void> {
  return new Promise((resolve, reject) => {
    function fun(itemList: MenuNodeInterface[]): MenuNodeClass[] {
      return itemList.map(item => {
        let itemClass = new MenuNodeClass(item);
        //添加按钮权限
        state.menuActionMap[item.pageName] = {
          add: true,
          delete: true,
          update: true
        };
        if (item.list && item.list.length > 0) {
          itemClass.list = fun(item.list)
        }
        return itemClass;
      });
    }
    //根据权限进行 调整
    let newmenus: MenuNodeInterface[] = menus.filter(item => {
      return (!item.vxList) || (item.vxList.indexOf(appState.grantType) >= 0)
      //这里暂时不进行权限管控,默认进入当前后台管理的 拥有全部权限
      return true;
    });

    state.menus = fun(newmenus);

    //添加额外的权限
    // let btnVxList = btnList[(appState.userInfo.GrantType as any)];
    // if(btnVxList){
    //   for(let pageName in btnVxList){
    //     if(state.menuActionMap[pageName]){
    //       //表示这个页面存在
    //       let list = (btnVxList as any)[pageName];
    //       for(let key of list){
    //         state.menuActionMap[pageName][key] = true;
    //       }
    //     }
    //   }
    // }

    resolve();
  })
}

/**
 * ================================
 *  appStore 的初始化
 * ================================
 */


/**
 * 将app中的数据添加到会话中进行保存
 */
const STORAGE_KEY = '--APP-STORAGE--';

let sessionStorageData = JSON.parse(getStorage(STORAGE_KEY) || "{}");

for (let x in sessionStorageData) {
  if (["isAppShow"].indexOf(x) < 0 && typeof (state as any)[x] != "undefined") {
    (state as any)[x] = sessionStorageData[x];
  }
}

watch(state, () => {
  let rawData = toRaw(state);
  setStorage(STORAGE_KEY, JSON.stringify(rawData), 8 * 60 * 60 * 1000)//仅存储1天
  // window.localStorage.setItem(STORAGE_KEY, JSON.stringify(rawData))
})